#include "arena_2dfood.h"
#include <iostream>

using namespace std;

Arena_2dfood::Arena_2dfood()
{
  reset();

  objects = new Objects(200, 200);
  Circle c(170, 30, 5);
  objects->add(c);
  Rectangle r(160 - _distance_to_food_x * 10, 20 + _distance_to_food_y * 10,
      20, 20);
  objects->add(r);

  update(0.0);
}

Arena_2dfood::~Arena_2dfood()
{
}

void Arena_2dfood::reset(void)
{
  _distance_to_food_x = 10;
  _distance_to_food_y = 14;
  _speed_x = 0;
  _speed_y = 0;
  Arena_base::reset();
}

float Arena_2dfood::get_distance_to_food(void)
{
  return _distance_to_food;
}

void Arena_2dfood::set_speed_x(float speed)
{
  //cout << "  Setting speed to " << speed << endl;
  _speed_x = speed;
}

void Arena_2dfood::set_speed_y(float speed)
{
  //cout << "  Setting speed to " << speed << endl;
  _speed_y = speed;
}

void Arena_2dfood::eat(float volume)
{
  if (_distance_to_food > 1) {
    cout << "  COULD NOT EAT: Distance too large: " << _distance_to_food
        << endl;
    return;
  }
  volume = 1.0;
  cout << "  Eating" << endl;
}

void Arena_2dfood::update(float time)
{
  if (time < _time) {
    cout << "ERROR: delta time negative" << endl;
    exit(1);
  }
  _distance_to_food_x -= _speed_x * (time - _time);
  _distance_to_food_y -= _speed_y * (time - _time);
  _distance_to_food = (_distance_to_food_x + _distance_to_food_y)
      * (_distance_to_food_x + _distance_to_food_y);
  //cout << "  Distance to food: " << _distance_to_food << endl;
  _time = time;
  print_state_to_file();
  _speed_x = 0.0;
  _speed_y = 0.0;

  update_arena();
}

float *Arena_2dfood::get_distance_to_food_p(void)
{
  return &_distance_to_food;
}

float *Arena_2dfood::get_distance_to_food_x_p(void)
{
  return &_distance_to_food_x;
}

float *Arena_2dfood::get_distance_to_food_y_p(void)
{
  return &_distance_to_food_y;
}

boost::function<void(float)> Arena_2dfood::set_speed_x_function(void)
{
  return std::bind1st(std::mem_fun(&Arena_2dfood::set_speed_x), this);
}

boost::function<void(float)> Arena_2dfood::set_speed_y_function(void)
{
  return std::bind1st(std::mem_fun(&Arena_2dfood::set_speed_y), this);
}

boost::function<void(float)> Arena_2dfood::eat_function(void)
{
  return std::bind1st(std::mem_fun(&Arena_2dfood::eat), this);
}

std::string Arena_2dfood::get_state(void)
{
  char s[400];

  sprintf(s, "%5.2f: d=%8.3f,%8.3f, v=%8.3f,%8.3f", _time, _distance_to_food_x,
      _distance_to_food_y, _speed_x, _speed_y);

  return string(s);
}

void Arena_2dfood::update_arena(void)
{
  objects->rectangles[0].p1.x = 160 - _distance_to_food_x * 10;
  objects->rectangles[0].p1.y = 20 + _distance_to_food_y * 10;
}
